package com.sluggard.security.core.manage;

import com.sluggard.security.core.manage.mapping.MappingParser;
import com.sluggard.security.core.manage.mapping.PostMappingParser;
import com.sluggard.security.core.manage.mapping.RequestMappingParser;
import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.security.authorization.AuthorizationDecision;
import org.springframework.security.authorization.AuthorizationManager;
import org.springframework.security.core.Authentication;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Supplier;

import static com.sluggard.security.core.consts.SecurityConstant.RESOURCE_PREFIX;

//@Component
public class MyAuthorizationManagerBeforeMethodInterceptor implements AuthorizationManager<MethodInvocation> {
    private final MappingParser methodParser;
    private final MappingParser classParser;

    public MyAuthorizationManagerBeforeMethodInterceptor() {
        this.methodParser = new PostMappingParser();
        this.classParser = new RequestMappingParser();
    }

    @Override
    public AuthorizationDecision check(Supplier<Authentication> authentication, MethodInvocation object) {
        List<String> urlList = getUrl(object);
        Optional<String> optional = authentication.get().getAuthorities().stream()
                .map(item -> StringUtils.removeEnd(item.getAuthority(), "/"))
                .filter(item -> StringUtils.startsWith(item, RESOURCE_PREFIX))
                .filter(urlList::contains)
                .findAny();
        return new AuthorizationDecision(optional.isPresent());
    }

    private List<String> getUrl(MethodInvocation object) {
        List<String> stringArrayList = new ArrayList<>();
        // 全部请求采用POST方式
        String[] mappings = methodParser.getMapping(object.getMethod());
        if (Objects.nonNull(mappings)) {
            // 获取类上的mapping注解路径
            String[] classMappings = classParser.getMapping(object.getMethod().getDeclaringClass());
            if (Objects.nonNull(classMappings)) {
                for (String classMapping : classMappings) {
                    String url = "/" + classMapping + "/";
                    if (mappings.length == 0) {
                        String resultUrl = url.replace("//", "/");
                        stringArrayList.add(StringUtils.removeEnd(resultUrl, "/"));
                        continue;
                    }
                    for (String mapping : mappings) {
                        String resultUrl = url + mapping;
                        // 处理 //
                        stringArrayList.add(resultUrl.replace("//", "/"));
                    }
                }
            }
        }
        return stringArrayList;
    }
}
